//
//  ViewController.m
//  Learn_SDWebImage_4.x
//
//  Created by Spring on 2017/12/24.
//  Copyright © 2017年 Spring. All rights reserved.
//

#import "ViewController.h"


//变量定义
typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
static NSString *const kProgressCallbackKey = @"progress";
static NSString *const kCompletedCallbackKey = @"completed";

@interface ViewController ()

//属性定义
@property (strong, nonatomic, nonnull) NSMutableArray<SDCallbacksDictionary *> *callbackBlocks;  //!<回调Block列表
@property (strong, nonatomic, nullable) dispatch_queue_t barrierQueue;  //!<一个并行queue，用于控制数据的处理
 
@end

@implementation ViewController
 

- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_queue_t queue = dispatch_queue_create("com.gcd.test", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 10; i++)
    {
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_async(queue, ^{
            NSLog(@"%i %@",i, [NSThread currentThread]);
            sleep(1);
            dispatch_semaphore_signal(semaphore);
        });
    }
 }

- (void)test{
    
    //调用
    _barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderOperationBarrierQueue", DISPATCH_QUEUE_CONCURRENT);
    _callbackBlocks = [NSMutableArray new];
    
    [self addHandlersForProgress:@"AA" completed:@"11"];
    [self addHandlersForProgress:@"BB" completed:@"22"];
    
    
    //手动加一条
    SDCallbacksDictionary *callbacks = [NSMutableDictionary new];
    callbacks[@"CC"] = @"33";
    callbacks[@"DD"] = @"44";
    dispatch_barrier_sync(self.barrierQueue, ^{
        [self.callbackBlocks addObject:callbacks];
        NSLog(@"手动加 callbackBlocks : \r\n%@", self.callbackBlocks);
        NSLog(@"手动加 callbacks : \r\n%@", callbacks);
    });
    
    [self callbacksForKey:kProgressCallbackKey];
    [self cancel:[self.callbackBlocks objectAtIndex:0]];

}


//方法定义
/**
 给Operation添加进度和回调Block
 
 @param progressBlock 进度Block
 @param completedBlock 回调Block
 @return 回调字典
 */
- (nullable id)addHandlersForProgress:(NSString *)progressBlock
                            completed:(NSString *)completedBlock {
    SDCallbacksDictionary *callbacks = [NSMutableDictionary new];
    //把Operation对应的回调和进度Block存入一个字典中
    if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy];
    if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy];
    //把完成和进度Block加入callbackBlocks中
    dispatch_barrier_async(self.barrierQueue, ^{
        [self.callbackBlocks addObject:callbacks];
        NSLog(@"addHandlersForProgress callbackBlocks : \r\n%@", self.callbackBlocks);
        NSLog(@"addHandlersForProgress callbacks : \r\n%@", callbacks);
    });
    
    return callbacks;
}

/**
 根据key取出所有符合key的block
 
 @param key key
 @return 符合key的block
 */
- (nullable NSArray<id> *)callbacksForKey:(NSString *)key {
    __block NSMutableArray<id> *callbacks = nil;
    dispatch_sync(self.barrierQueue, ^{
        
        callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy];
        NSLog(@"callbacksForKey callbackBlocks : \r\n%@", self.callbackBlocks);
        NSLog(@"callbacksForKey Before Remove Null callbacks : \r\n%@", callbacks);
        [callbacks removeObjectIdenticalTo:[NSNull null]];
        NSLog(@"callbacksForKey After Remove Null callbacks : \r\n%@", callbacks);
    });
    return [callbacks copy];    // strip mutability here
}

/**
 取消某一回调
 
 @param token 和addHandlersForProgress:completed:方法的返回值对应
 @return YES/NO
 */
- (BOOL)cancel:(nullable id)token {
    __block BOOL shouldCancel = NO;
    dispatch_barrier_sync(self.barrierQueue, ^{
        NSLog(@"cancel Before Remove callbackBlocks : \r\n%@", self.callbackBlocks);
        
        [self.callbackBlocks removeObjectIdenticalTo:token];
        
        NSLog(@"cancel After Remove callbackBlocks : \r\n%@", self.callbackBlocks);
        if (self.callbackBlocks.count == 0) {
            shouldCancel = YES;
        }
    });
    return shouldCancel;
}

    @end
